﻿/*
 *  date: 2018-04-21
 *  author: John-chen
 *  cn: 基础游戏APP,用来定义游戏流程
 *  en: todo:
 */

using System.Linq;
using System.Collections.Generic;
using UnityEngine;

namespace JyFramework
{
    /// <summary>
    /// 基础游戏APP,用来定义游戏流程
    /// </summary>
    public class BaseApp : IGameLife
    {
        /*
         * 游戏框架的核心基类
         * 管理游戏生命周期和模块的生命周期，所有dll初始化，所有模块初始化
         *
         * 按初始化顺序包括了：
         *      日志、时间、数据、事件、线程、脚本
         *      网络、资源、UI
         *      音频、对象池、AI、工具
         *  等模块
         *
         *  todo: 在后期，可能会把一些模块封装到dll中去
         */
        /// <summary>
        /// GameApp名字
        /// </summary>
        public string Name { get { return _name; } }

        /// <summary>
        /// 游戏版本
        /// </summary>
        public string Version{ get { return _version; } }

        /// <summary>
        /// 初始化游戏
        /// </summary>
        public virtual void InitGame()
        {
            Debug.Log("BaseApp InitGame----------------");
            AddModules();
        }

        /// <summary>
        /// 开始游戏
        /// </summary>
        public virtual void StartGame()
        {
            foreach (var m in _modules.Values)
            {
                m.StartGame();
            }
        }

        /// <summary>
        /// 每帧更新
        /// </summary>
        /// <param name="deltaTime"></param>
        public virtual void UpdateGame(float deltaTime)
        {
            //Debug.Log("BaseApp Update!");
            for (int i = 0; i < _moduleCnt; i++)
            {
                moduleArray[i].UpdateGame(deltaTime);
            }
        }

        /// <summary>
        /// 暂停游戏
        /// </summary>
        public virtual void PauseGame()
        {
            foreach (var m in _modules.Values)
            {
                m.PauseGame();
            }
        }

        /// <summary>
        /// 退出游戏
        /// </summary>
        public virtual void ExitGame()
        {
            foreach (var m in _modules.Values)
            {
                m.ExitGame();
            }
        }

        /// <summary>
        /// 基本用不到,高层一般用Manager内的就行了
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T GetModule<T>(string name) where T : BaseModule
        {
            if (_modules.ContainsKey(name))
                return (T)_modules[name];

            return null;
        }

        /// <summary>
        /// 移除Module
        /// </summary>
        public void RemoveModule(BaseModule module)
        {
            if (module == null) return;
            if (!_modules.ContainsKey(module.Name))
            {
                module.ClearSelf();
                return;
            }
            _modules.Remove(module.Name);
            module.ClearSelf();

            RegetModuleList();
        }

        /// <summary>
        /// 清除所有module
        /// </summary>
        public void RemoveAllModules()
        {
            if (_modules == null) return;
            foreach (var module in _modules)
            {
                module.Value.ClearSelf();
            }

            _modules.Clear();

            RegetModuleList();
        }

        private BaseModule[] _moduleArray;

        protected string _name;
        protected int _moduleCnt;
        protected string _version;
        protected Dictionary<string, BaseModule> _modules;

        protected BaseModule[] moduleArray
        {
            get
            {
                if (_moduleArray == null)
                {
                    RegetModuleList();
                }
                return _moduleArray;
            }
        }

        /// <summary>
        /// 重新获取一次模块列表
        /// </summary>
        private void RegetModuleList()
        {
            _moduleArray = _modules.Values.ToArray();
            _moduleCnt = _moduleArray.Length;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="name"> 游戏名 </param>
        protected BaseApp(string name = "BaseApp")
        {
            Debug.Log("Base App ctor----------------");
            _name = name;
            _moduleCnt = 0;
            _modules = new Dictionary<string, BaseModule>();

            #region 设置运行顺序
            // 读取配置文件
            ReadConfig();

            // 初始化所有引入的dll
            InitDlls();
            #endregion
        }

        /// <summary>
        /// 读取配置表
        /// </summary>
        protected virtual void ReadConfig()
        {
            Debug.Log("Base App ReadConfig----------------");
        }

        /// <summary>
        /// 初始化dll
        /// </summary>
        protected virtual void InitDlls()
        {
            Debug.Log("Base App InitDlls----------------");
        }

        /// <summary>
        /// 添加模块到框架中,并且初始化自己
        /// </summary>
        /// <param name="moduleName"></param>
        /// <param name="module"></param>
        protected virtual void AddModule(string moduleName, BaseModule module)
        {
            if (module == null || _modules == null) return;

            if (_modules.ContainsKey(moduleName))
            {
                _modules[moduleName] = module;
            }
            else
            {
                _modules.Add(moduleName, module);
                module.InitGame();
            }

            RegetModuleList();
        }

        /// <summary>
        /// 添加所有的模块
        /// </summary>
        protected virtual void AddModules()
        {
            
        }
    }
}